package com.biz.primus.ms.auth.dao.po;

import com.biz.primus.base.enums.CommonStatus;
import java.util.List;
import java.util.Objects;
import javax.persistence.*;
import javax.validation.constraints.NotNull;

import com.biz.primus.model.sso.auth.vo.IDescribableItem;
import com.biz.primus.ms.base.jpa.po.BaseEntity;
import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import org.hibernate.annotations.Where;
import org.hibernate.validator.constraints.NotBlank;

@Entity
@Table(name = "auth_menugroup", uniqueConstraints = {@UniqueConstraint(columnNames = {"applicationType", "customId"})})
public class MenuGroup extends BaseEntity implements ICustomIdAble, IDescribableItem {

    private static final long serialVersionUID = -6119734988526076949L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(length = 64)
    private String applicationType;

    @Column(length = 64, nullable = false)
    private String customId;

    @Column
    private Integer orderIndex;

    @Column(length = 200)
    @NotNull(message = "名称不能为空")
    @NotBlank(message = "名称不能为空")
    private String name;

    @Column
    private String description;

    @Column(length = 20)
    @NotNull(message = "图标不能为空")
    @NotBlank(message = "图标不能为空")
    private String icon = "fa fa-list";

    /**
     * Where这个条件的意思是进行(MainMenu与MenuItem)关联查询的时候,我只把MenuItem中status = ENABLE的查询出来.
     */
    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "menuGroup")
    @OrderBy(value = "orderIndex")
    @Where(clause = "status='ENABLE'")
    private List<MenuItem> menuItems;

    @JsonBackReference
    @ManyToOne(fetch = FetchType.LAZY)
    private MenuGroup parent;

    @JsonManagedReference
    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "parent")
    @Where(clause = "status='ENABLE'")
    private List<MenuGroup> children;

    @Column
    @Enumerated(EnumType.STRING)
    private CommonStatus status = CommonStatus.ENABLE;

    public MenuGroup() {

    }

    public MenuGroup(String customId) {
        this.customId = customId;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o)
            return true;
        if (!(o instanceof MenuGroup))
            return false;

        MenuGroup other = (MenuGroup) o;
        return id != null && Objects.equals(this.getId(), other.getId()) || Objects.equals(applicationType, other.getApplicationType()) && Objects.equals(customId, other.getCustomId());
    }

    @Override
    public int hashCode() {
        if (id != null) {
            return id.hashCode();
        } else {
            int result = (applicationType != null ? applicationType.hashCode() : 0);
            result = 31 * result + (customId != null ? customId.hashCode() : 0);
            return result;
        }
    }

    /**
     * {@linkplain MenuGroup#id}
     */
    @Override
    public Long getId() {
        return id;
    }

    /**
     * {@linkplain MenuGroup#id}
     */
    @Override
    public void setId(Long id) {
        this.id = id;
    }

    /**
     * {@linkplain MenuGroup#applicationType}
     */
    public String getApplicationType() {
        return applicationType;
    }

    /**
     * {@linkplain MenuGroup#applicationType}
     */
    public void setApplicationType(String applicationType) {
        this.applicationType = applicationType;
    }

    /**
     * {@linkplain MenuGroup#customId}
     */
    public String getCustomId() {
        return customId;
    }

    /**
     * {@linkplain MenuGroup#customId}
     */
    public void setCustomId(String customId) {
        this.customId = customId;
    }

    /**
     * {@linkplain MenuGroup#orderIndex}
     */
    public Integer getOrderIndex() {
        return orderIndex;
    }

    /**
     * {@linkplain MenuGroup#orderIndex}
     */
    public void setOrderIndex(Integer orderIndex) {
        this.orderIndex = orderIndex;
    }

    /**
     * {@linkplain MenuGroup#name}
     */
    public String getName() {
        return name;
    }

    /**
     * {@linkplain MenuGroup#name}
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * {@linkplain MenuGroup#description}
     */
    public String getDescription() {
        return description;
    }

    /**
     * {@linkplain MenuGroup#description}
     */
    public void setDescription(String description) {
        this.description = description;
    }

    /**
     * {@linkplain MenuGroup#icon}
     */
    public String getIcon() {
        return icon;
    }

    /**
     * {@linkplain MenuGroup#icon}
     */
    public void setIcon(String icon) {
        this.icon = icon;
    }

    /**
     * {@linkplain MenuGroup#menuItems}
     */
    public List<MenuItem> getMenuItems() {
        return menuItems;
    }

    /**
     * {@linkplain MenuGroup#menuItems}
     */
    public void setMenuItems(List<MenuItem> menuItems) {
        this.menuItems = menuItems;
    }

    /**
     * {@linkplain MenuGroup#parent}
     */
    public MenuGroup getParent() {
        return parent;
    }

    /**
     * {@linkplain MenuGroup#parent}
     */
    public void setParent(MenuGroup parent) {
        this.parent = parent;
    }

    /**
     * {@linkplain MenuGroup#children}
     */
    public List<MenuGroup> getChildren() {
        return children;
    }

    /**
     * {@linkplain MenuGroup#children}
     */
    public void setChildren(List<MenuGroup> children) {
        this.children = children;
    }

    /**
     * {@linkplain MenuGroup#status}
     */
    public CommonStatus getStatus() {
        return status;
    }

    /**
     * {@linkplain MenuGroup#status}
     */
    public void setStatus(CommonStatus status) {
        this.status = status;
    }
}
